前輩常常會提醒說不要重造輪子,所以在開發時,如果有一個可以覆用的需求,就會想說這個應該有人作過吧,就去找有沒有相應的函式庫,像是 Java 常見的就是 apache 的 StringUtils, IOUtils。 Kotlin 也自帶了很多好用的抽象化方法。如我想取得一個值是要在 0 - 100 之間,超過就當 100, 低於就當 0,我們可能會這樣寫
val percent = when {
numberFromUser > 100 -> 100
numberFromUser < 0 -> 0
else -> numberFromUser
}
那其實 Kotlin 已經有內建這樣的函式叫 coerceIn
val percent = numberFromUser.coerceIn(0, 100)
不過這世界上好用的函式這麼多,要怎麼避免重造輪子呢?有幾個方向
常見的演算法幾乎總是已經被某人定義過。大多數的函式庫只是常見算法的集合。其中最特殊的是 stdlib(標準庫)。它是一個巨大的工具集,主要定義為擴展函數。學習 stdlib 函數可能需要很大的努力,但這是值得的。沒有它,開發者一次又一次地重新發明輪子。
舉一個例子,這是一個開源專案中的一段程式碼:
override fun saveCallResult(item: SourceResponse) {
var sourceList = ArrayList<SourceEntity>()
item.sources.forEach {
var sourceEntity = SourceEntity()
sourceEntity.id = it.id
sourceEntity.category = it.category
sourceEntity.country = it.country
sourceEntity.description = it.description
sourceList.add(sourceEntity)
}
db.insertSources(sourceList)
}
使用 forEach 在這裡是沒有意義的。看不出使用它代替 for-loop 的優點。但在這段程式碼中看到的是一種類型到另一種類型的映射。在這種情況下,我們可以使用 collection 的map。還要注意的是,SourceEntity 的建立方式並非完美。這是在 Kotlin 中已過時的 JavaBean 模式,我們應該使用工廠方法或主建構子。如果有人需要保持這種方式,我們至少應該使用 apply來設置單一對象的所有屬性。這是在小小清理後的的程式
override fun saveCallResult(item: SourceResponse) {
val sourceEntries = item.sources.map(::sourceToEntry)
db.insertSources(sourceEntries)
}
private fun sourceToEntry(source: Source) = SourceEntity().apply {
id = source.id
category = source.category
country = source.country
description = source.description
}
還好,標準函式庫有人幫我驟細心整理了。最後就來推薦這本,
聖佑從鐵人賽到去年出書的
[Kotlin Collection全方位解析攻略 : 精通原理及實戰,寫出流暢好維護的程式(iT邦幫忙鐵人賽系列書)] https://www.books.com.tw/products/0010928334
工程師就是要口袋有許多法寶,需要時拿出來用。這就是 My Bag
聖佑到底是怎麼收買 Brandy 大大的...
從 Coscup 幫工商到 鐵人賽
It邦幫忙,以後可能會改成為
It幫工商
XD